﻿using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Text;
using System.Globalization;

namespace ConsoleApp
{
    internal class SystemInfoHelper
    {

        #region Environment类：与执行环境相关的信息，包括操作系统版本、可用处理器数量、当前工作目录等。它还可以用来访问一些系统环境变量，以及控制程序的输入和输出
        /// <summary>
        /// 获取操作系统版本
        /// </summary>
        public static string GetOSVersion()
        {
            return Environment.Version.ToString();
        }

        /// <summary>
        /// 获取CPU的数目
        /// </summary>
        /// <returns></returns>
        public static int GetCPUCount()
        {
            return Environment.ProcessorCount;
        }

        /// <summary>
        /// 获取当前的工作目录
        /// </summary>
        /// <returns></returns>
        public static string GetCurrentDirectory()
        {
            return Environment.CurrentDirectory;
        }

        /// <summary>
        /// 从环境变量中获取值
        /// </summary>
        /// <returns></returns>
        public static string? GetEnvironmentVariable()
        {
            return Environment.GetEnvironmentVariable("PATH");
        }

        #endregion

        #region Process类：获取当前正在运行的进程的信息，包括进程ID、名称、CPU使用率等

        public void Demo1()
        {
            var processes = Process.GetProcesses();
            foreach (var process in processes)
            {
                Console.WriteLine("Process Name: " + process.ProcessName);
                Console.WriteLine("CPU Usage: " + process.TotalProcessorTime);
            }
        }
        #endregion
        
        /// <summary>
        /// 测试服务器的上传和下载速度
        /// </summary>
        public void Network()
        {
            //要获取服务器的上传和下载速率，您可以使用 System.Net 命名空间中的 NetworkInterface 类和 SpeedTest 类。
            // 获取所有网络接口
            var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

            // 遍历每个网络接口
            foreach (var networkInterface in networkInterfaces)
            {
           
                // 获取接口的上行和下行流量（以字节为单位）
                var upBytes = networkInterface.GetIPv4Statistics().BytesReceived;
                var downBytes = networkInterface.GetIPv4Statistics().BytesSent;

                Console.WriteLine($"Interface: {networkInterface.Name}");
                Console.WriteLine($"  Upstream: {upBytes} bytes");
                Console.WriteLine($"  Downstream: {downBytes} bytes");
            }
        }

        // DriveInfo类: 提供有关计算机驱动器的信息，包括总扇区数、可用扇区数、总字节数、可用字节数等等。
        public static void GetDriveInfo()
        {
            var drives = DriveInfo.GetDrives();

            foreach (var drive in drives)
            {
                Console.WriteLine("Drive: " + drive.Name);
                var totalSize = drive.TotalSize / 1024 / 1024 / 1024;
                var totalFree = drive.TotalFreeSpace / 1024 / 1024 / 1024;//drive.AvailableFreeSpace

                Console.WriteLine("  Total Size: " + totalSize);
                Console.WriteLine("  Free Size: " + totalFree);
                Console.WriteLine("  Used Size: " + (totalSize - totalFree));
                Console.WriteLine();
            }
        }
        
        public void Run()
        {
            var sb = new StringBuilder();

            //机器的CPU内核数
            var processorCount = Environment.ProcessorCount;
            sb.AppendLine("机器的CPU内核数=" + processorCount);

            //获取当前进程
            var currentProcess = Process.GetCurrentProcess();
            //var processId = CurrentProcess.Id;//PID
            //获取当前进程CPU利用率
            var tmpRate =
                Math.Round(
                    currentProcess.UserProcessorTime.TotalMilliseconds * 100 /
                    currentProcess.TotalProcessorTime.TotalMilliseconds, 2);
            var cpuUsage = tmpRate + "%"; //CPU
                                            //获取当前进程内存占用
            var memoryUsage = (currentProcess.WorkingSet64 / 1024 / 1024).ToString(CultureInfo.InvariantCulture) + "M (" +
                                (currentProcess.WorkingSet64 / 1024).ToString(CultureInfo.InvariantCulture) + "KB)";
            //占用内存
            //获取当前进程的线程数
            var threadCount = currentProcess.Threads.Count; //线程

            //获取当前进程的线程池大小
            ThreadPool.GetMaxThreads(out var maxThread, out var maxThread2); //线程
            ThreadPool.GetAvailableThreads(out var avThread, out var avThread2);
            ThreadPool.GetMinThreads(out var mThread, out var mThread2);

            var threadPoolInfo = $"线程池大小={maxThread2}/{maxThread}, 线程池可用线程数={avThread2}/{avThread}, 线程池最小线程数={mThread2}/{mThread}";

            sb.AppendLine("当前进程CPU利用率=" + cpuUsage);
            sb.AppendLine("当前进程内存占用=" + memoryUsage);
            sb.AppendLine("当前进程的线程数=" + threadCount);
            sb.AppendLine(threadPoolInfo);

            var bestThreadInfo = string.Empty;
            //最佳线程数为
            var bestThreadCountTmp = currentProcess.TotalProcessorTime.TotalMilliseconds /
                                        (currentProcess.UserProcessorTime.TotalMilliseconds / threadCount);
            bestThreadInfo += "最佳线程数=" + bestThreadCountTmp + ",";

            //如果需要增加线程
            if (Math.Abs(bestThreadCountTmp - maxThread) > 1)
            {
                if (tmpRate < 90 && bestThreadCountTmp > 400)
                {
                    int bestThreadCount = (int)Math.Floor(bestThreadCountTmp);
                    //ThreadPool.SetMinThreads(bestThreadCount, bestThreadCount);
                    ThreadPool.SetMaxThreads(bestThreadCount, bestThreadCount);
                    bestThreadInfo += "重设线程池的MaxThreads=" + bestThreadCount + ",";
                }
            }
            sb.AppendLine(bestThreadInfo);

            var phisicalMemory = 100000;//GetPhisicalMemory();
            sb.AppendLine("MemoryCapacity=" + phisicalMemory + "M");

            var ramCounter = new PerformanceCounter("Memory", "Available MBytes");
            double available = ramCounter.NextValue();

            ////获取内存可用大小
            //ManagementClass cimobject2 = new ManagementClass("Win32_PerfFormattedData_PerfOS_Memory");
            //ManagementObjectCollection moc2 = cimobject2.GetInstances();
            //foreach (ManagementObject mo2 in moc2)
            //{
            //    available += int.Parse(mo2.Properties["AvailableMBytes"].Value.ToString();
            //}
            //moc2.Dispose();
            //cimobject2.Dispose();

            sb.AppendLine("MemoryAvailable=" + available + "M");
            sb.AppendLine("MemoryUsed=" + (phisicalMemory - available) + "M，" +
                            Math.Round(((phisicalMemory - available) / phisicalMemory * 100), 2) + "％");

            var cpuCounter = new PerformanceCounter
            {
                CategoryName = "Processor",
                CounterName = "% Processor Time",
                InstanceName = "_Total"
            };
            sb.AppendLine("总CPU利用率=" + cpuCounter.NextValue() + "%");

            // // Get the WMI class  
            // ManagementClass cc = new ManagementClass(new ManagementPath("Win32_Processor"));     
            // // Get the properties in the class     
            // ManagementObjectCollection moc = cc.GetInstances();    
            // foreach (ManagementObject mo in moc)
            // {
            //     PropertyDataCollection properties = mo.Properties; //获取内核数代码    
            //     Console.WriteLine("物理内核数:" + properties["NumberOfCores"].Value);
            //     Console.WriteLine("逻辑内核数:" + properties["NumberOfLogicalProcessors"].Value);
            //     //其他属性获取代码    
            //     foreach (PropertyData property in properties)
            //     {
            //         Console.WriteLine(property.Name + ":" + property.Value);
            //     }
            // }
            // moc.Dispose();
            // cc.Dispose();

            var sb2 = new StringBuilder();
            sb2.AppendLine("&机器的CPU内核数=" + processorCount);
            sb2.AppendLine("&当前进程CPU利用率=" + cpuUsage);
            sb2.AppendLine("&当前进程内存占用=" + memoryUsage);
            sb2.AppendLine("&当前进程的线程数=" + threadCount);
            sb2.AppendLine("&" + threadPoolInfo);
            sb2.AppendLine("&" + bestThreadInfo);
            sb2.AppendLine("&MemoryCapacity=" + phisicalMemory + "M");
            sb2.AppendLine("&MemoryAvailable=" + available + "M");
            sb2.AppendLine("&MemoryUsed=" + (phisicalMemory - available) + "M，" +
                            Math.Round(((phisicalMemory - available) / phisicalMemory * 100), 2) + "％");
            sb2.AppendLine("&总CPU利用率=" + cpuCounter.NextValue() + "%");
            Console.WriteLine(sb.ToString());
            Console.WriteLine(sb2.ToString());
        }
    }
}
